use std::time::{SystemTime, UNIX_EPOCH};
use actix_web::{get, post, web, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use sqlx::MySqlPool;
use crate::dao::user_dao::UserDao;
use crate::services::user_service::UserService;
use jsonwebtoken::{encode, Header, EncodingKey};
use crate::models::response_object::ResponseObject;

// 定义处理函数
#[get("/users")]
async fn get_users(pool: web::Data<MySqlPool>) -> impl Responder {
    let user_dao = UserDao::new(pool.get_ref().clone()); // 假设有一个 UserDao 实例的创建逻辑
    let user_service = UserService::new(user_dao);
    match user_service.get_all_users().await {
        Ok(users) => HttpResponse::Ok().json(users), // 成功时返回用户列表的JSON数据
        Err(err) => HttpResponse::InternalServerError().body(err), // 失败时返回错误信息
    }
}

#[post("/users")]
async fn create_user() -> impl Responder {
    let response = UserService::get_users();
    HttpResponse::Ok().json(response)}

#[derive(Serialize)]
struct MyObj {
    name: String,
}

#[get("/a/{name}")]
async fn index(name: web::Path<String>,    pool: web::Data<MySqlPool>) -> actix_web::Result<impl Responder> {
    let obj = MyObj {
        name: name.to_string(),
    };
    Ok(web::Json(obj))
}

#[derive(Deserialize)]
struct AuthRequest {
    username: String,
    password: String,
}

#[derive(Serialize, Deserialize)]
struct Claims {
    sub: String,   // 用户标识符
    exp: usize,    // 过期时间
}

#[post("/login")]
async fn login(auth: web::Json<AuthRequest>) -> impl Responder {
    // 这里我们直接将用户名和密码用于演示，实际中应该验证用户名和密码
    if auth.username == "user" && auth.password == "password" {
        match create_jwt(&auth.username) {
            Ok(token) => HttpResponse::Ok().json( ResponseObject::success_with_data(token)),
            Err(_) => HttpResponse::InternalServerError().body("Error generating JWT"),
        }
    } else {
        HttpResponse::Ok().json( ResponseObject::success_with_data("登录失败"))
    }
}
const SECRET_KEY: &[u8] = b"my_secret_key"; // 密钥
fn create_jwt(username: &str) -> Result<String, Box<dyn std::error::Error>> {
    // 设置过期时间为 1 小时后
    let expiration = SystemTime::now()
        .duration_since(UNIX_EPOCH)?
        .as_secs() + 3600; // 3600 秒 = 1 小时

    let claims = Claims {
        sub: username.to_string(),
        exp: expiration as usize,
    };

    let header = Header::new(jsonwebtoken::Algorithm::HS256);
    let token = encode(&header, &claims, &EncodingKey::from_secret(SECRET_KEY))?;

    Ok(token)
}

// 函数用于返回路由配置
pub fn user_routes(cfg: &mut web::ServiceConfig) {
    cfg.service(index);
    cfg.service(get_users);
    cfg.service(create_user);
    cfg.service(login);

}
